//
//  String+Extension.swift
//  CommonTool
//
//  Created by tenroadshow on 12.1.22.
//

import UIKit

public extension String {
    static func isNilOrEmpty(text: String?) -> Bool {
        if let value = text, !value.isEmpty {
            return false
        }else {
            return true
        }
    }
}

public enum NNRegexType: String {
     case isPhone = "^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}$"
     /// 身份证
     case idCard = "^\\d{17}[0-9Xx]|\\d{15}"
     /// 数字
     case isDigital = "^[0-9]+$"
     /// 字母
     case isLetter = "^[a-zA-Z]+$"
     /// 数字和字母
     case isDigitalAndLetter = "^[a-zA-Z0-9]+$"
     /// 中文
     case isChinese = "^[\\u4E00-\\u9FA5]+$"
     // 中文+字母+数字
     case isChineseDigitalAndLetter = "^([A-Za-z]|[\\u4E00-\\u9FA5]|[0-9])+$"
     // 中文+字母+数字+特殊字符
     case isChineseDigitalAndLetterAndMore = "^([A-Za-z]|[\\u4E00-\\u9FA5]|[0-9]|[_^%&',;=?$\"])+$"
     /// 邮箱
     case isEmail = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,100}"
     /// 是否包含中文
     case hasDigital = ".*[0-9]+.*"
     case hasLetter = ".*[a-zA-Z]+.*"
     case hasDigitalAndLetter = ".*[a-zA-Z0-9]+.*"
     case hasChiness = ".*[\\u4E00-\\u9FA5}]+.*"
 }


public extension String {
    // 判断是否匹配
    func isMatch(regex: NNRegexType) -> Bool {
        let predicate = NSPredicate(format: "SELF MATCHES %@", regex.rawValue)
        return predicate.evaluate(with: self)
    }
}

extension String {
    
    func tn_nsRange<T: StringProtocol>(of content: T) -> NSRange? {
        guard let range = range(of: content) else { return nil }
        return tn_nsRange(range)
    }
    
    
    func tn_nsRange(_ range: Range<String.Index>) -> NSRange {
        guard let from = range.lowerBound.samePosition(in: utf16),
              let to = range.upperBound.samePosition(in: utf16) else {
            return NSMakeRange(0, 0)
        }
        return NSMakeRange(utf16.distance(from: utf16.startIndex, to: from), utf16.distance(from: from, to: to))
    }

    func tn_range(_ range: NSRange) -> Range<String.Index>? {
        guard let from16 = utf16.index(utf16.startIndex, offsetBy: range.location, limitedBy: utf16.endIndex) else { return nil }
        guard let to16 = utf16.index(from16, offsetBy: range.length, limitedBy: utf16.endIndex) else { return nil }
        guard let from = String.Index(from16, within: self) else { return nil }
        guard let to = String.Index(to16, within: self) else { return nil }
        return from ..< to
    }

}



// MARK:- 十、字符串截取的操作
public extension String {
    // MARK: 1.7、判断是不是九宫格键盘
    /// 判断是不是九宫格键盘
    func isNineKeyBoard() -> Bool {
        let other : NSString = "➋➌➍➎➏➐➑➒"
        for _ in 0..<count {
            if !(other.range(of: self).location != NSNotFound) {
                return false
            }
        }
        return true
    }

    
    // MARK: 10.1、截取字符串从开始到 index
    /// 截取字符串从开始到 index
    /// - Parameter index: 截取到的位置
    /// - Returns: 截取后的字符串
    func sub(to index: Int) -> String {
        let end_Index = validIndex(original: index)
        return String(self[startIndex ..< end_Index])
    }
    
    // MARK: 10.2、截取字符串从index到结束
    /// 截取字符串从index到结束
    /// - Parameter index: 截取结束的位置
    /// - Returns: 截取后的字符串
    func sub(from index: Int) -> String {
        let start_index = validIndex(original: index)
        return String(self[start_index ..< endIndex])
    }
  

}


extension String {
    // MARK: 9.12、校验字符串位置是否合理，并返回String.Index
    /// 校验字符串位置是否合理，并返回String.Index
    /// - Parameter original: 位置
    /// - Returns: String.Index
    public func validIndex(original: Int) -> String.Index {
        switch original {
        case ...self.startIndex.utf16Offset(in: self):
            return startIndex
        case endIndex.utf16Offset(in: self)...:
            return endIndex
        default:
            return self.index(startIndex, offsetBy: original)
        }
    }

}


/// emoji
extension String {
    /// 是否为单个emoji表情
    public var isSingleEmoji: Bool {
        return count==1 && containsEmoji
    }

    /// 包含emoji表情
    public var containsEmoji: Bool {
        return contains{ $0.isEmoji }
    }

    /// 只包含emoji表情
    public var containsOnlyEmoji: Bool {
        return !isEmpty && !contains{ !$0.isEmoji }
    }

    /// 提取emoji表情字符串
    public var emojiString: String {
        return emojis.map{ String($0) }.reduce("",+)
    }

    /// 提取emoji表情数组
    public var emojis: [Character] {
        return filter{ $0.isEmoji }
    }
    /// 提取单元编码标量
    public var emojiScalars: [UnicodeScalar] {
        return filter{ $0.isEmoji }.flatMap{ $0.unicodeScalars}
    }
    
    public var removedEmoji: String {
        return filter{ !$0.isEmoji }.map{ String($0) }.reduce("",+)
    }
    
}

extension Character {
    /// 简单的emoji是一个标量，以emoji的形式呈现给用户
   public var isSimpleEmoji: Bool {
        guard let firstProperties = unicodeScalars.first?.properties else{
            return false
        }
        return unicodeScalars.count == 1 &&
            (firstProperties.isEmojiPresentation ||
                firstProperties.generalCategory == .otherSymbol)
    }

    /// 检查标量是否将合并到emoji中
    public var isCombinedIntoEmoji: Bool {
        return unicodeScalars.count > 1 &&
            unicodeScalars.contains { $0.properties.isJoinControl || $0.properties.isVariationSelector }
    }

    /// 是否为emoji表情
    public var isEmoji:Bool{
        return isSimpleEmoji || isCombinedIntoEmoji
    }
}


